package org.vacoor.xqq.hotkey;

import org.vacoor.xqq.hotkey.impl.win.JIntellitypeManager;
import org.vacoor.xqq.hotkey.impl.linux.JXGrabKeyManager;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ServiceLoader;

/**
 * 系统级快捷键
 *
 * User: Vacoor
 */
public abstract class OSHotKeyManager {

    /**
     * 该方法一般不需要调用, 仅用于内部判断是否支持当前系统
     * @return
     */
    protected abstract boolean supportCurrentOS();

    /**
     * @param identifier   功能唯一标示符
     * @return
     */
    public abstract OSHotKeyBinder getOSHotKeyBinder(int identifier);

    public abstract void destory();

    // --------------------------------------

    private static OSHotKeyManager currentHotKeyManager;
    private static boolean loaded;   // 是否已经加载过

    public static OSHotKeyManager getCurrentOSHotKeyManager() {
        if(currentHotKeyManager != null) {
            return currentHotKeyManager;
        }
        synchronized (OSHotKeyManager.class) {
            if(currentHotKeyManager == null && !loaded) {
                Iterable<OSHotKeyManager> hotKeyManagers = getHotKeyManagers();
                for(OSHotKeyManager ohkm : hotKeyManagers) {
                    if(ohkm.supportCurrentOS()) {
                        currentHotKeyManager = ohkm;
                        break;
                    }
                }
                loaded = true;
            }
        }
        return currentHotKeyManager;
    }

    private static Iterable<OSHotKeyManager> getHotKeyManagers() {
        List<OSHotKeyManager> providers = new ArrayList<OSHotKeyManager>();
        providers.add(new JXGrabKeyManager());
        providers.add(new JIntellitypeManager());
        return providers;
//        return getProviders(OSHotKeyManager.class);
    }

    private static <S> Iterable<S> getProviders(Class<S> providerClass) {
        ServiceLoader<S> providers = ServiceLoader.load(providerClass);
        return providers;
    }

    static int identifier = (int) new Date().getTime();

    public synchronized static int nextIdentifier() {
        return ++identifier;
    }
}
